﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BizzCommInterfaces;

namespace BizzCore
{
    class RulesHandler
    { 
        private static RulesHandler _instance = null;
        private List<Rule> _ruleList = null;

        protected RulesHandler()
        {
            _ruleList = new List<Rule>();
        }

        public static RulesHandler getInstance()
        {
            if (_instance == null)
                _instance = new RulesHandler();
            return _instance;
        }

        public void addRule(string name, string field, Condition con, string expectedValue, IOutbox outbox)
        {
            bool validName = name != "";
            bool validField = field != "";
            bool goAhead = validName && validField;

            if (goAhead)
            {
                try
                {
                    Rule theRule = new Rule(name, field, con, expectedValue, outbox);
                    using (BizzCommContext ctx = new BizzCommContext())
                    {
                        ctx.Trays.Attach(theRule.outboxEntity);
                        ctx.Rules.Add(theRule);
                        ctx.SaveChanges();
                    }
                    _ruleList.Add(theRule);
                }
                catch(Exception ex)
                {
                     string errormsg = "Se produjo un error al agregar la regla: " + ex.Message;
                     throw new Exception(errormsg);
                }   
            }
            else
            {
                throw new Exception("Por favor complete todos los campos");
            }
        }

        
        public void removeRule(Rule r)
        {
            try
            {
                using (BizzCommContext ctx = new BizzCommContext())
                {
                    ctx.Rules.Attach(r);
                    ctx.Rules.Remove(r);
                    ctx.SaveChanges();
                }
                _ruleList.Remove(r);
            }
            catch (Exception ex)
            {
                string errormsg = "Se produjo un error al agregar la regla: " + ex.Message;
                throw new Exception(errormsg);
            }
            
        }


        public List<Rule> getRuleList()
        {
            return _ruleList;
        }

        public List<Condition> getConditions()
        {
            List<Condition> ret = new List<Condition>();

            //equalsTo, lessThan, greaterThan, lessOrEqualsTo, greaterOrEqualsTo, notEqualsTo 
            Condition equalsTo = new Condition_equalsTo();
            ret.Add(equalsTo);
            Condition lessThan = new Condition_lessThan();
            ret.Add(lessThan);
            Condition greaterThan = new Condition_greaterThan();
            ret.Add(greaterThan);
            Condition lessOrEqualsTo = new Condition_lessOrEqualsTo();
            ret.Add(lessOrEqualsTo);
            Condition greaterOrEqualsTo = new Condition_greaterOrEqualsTo();
            ret.Add(greaterOrEqualsTo);
            Condition notEqualsTo = new Condition_notEqualsTo();
            ret.Add(notEqualsTo);

            return ret;
        }

        public void restoreRulesFromDB()
        {
            
            using (BizzCommContext ctx = new BizzCommContext())
            {
                var rules = (from r in ctx.Rules
                            select r).ToList();
                
                foreach (Rule r in rules)
                {
                    
                    
                    r._condition = (from c in getConditions()
                                   where c.ToString() == r.conditionString
                                   select c).Single();
                    r._outbox = TraysHandler.getInstance().getOutboxFromTrayEntity(r.outboxEntity);
                    _ruleList.Add(r);
                }

            }
        }

        public bool isOutBoxInUse(IOutbox outbox)
        {
            var query = (from r in _ruleList
                         where r._outbox == outbox
                         select r).FirstOrDefault();
            return query != null;
        }

    }
}
